

<Serializable()> Public Class Advantage
    Public [name] As String = "N/A"
    Public description As String = "none"
    Public turnGranted As Long = 0
    Public contract As IExpirationContract = New NonExpiringContract
    Public effect As IGeneralEffect = New NoEffectGeneralEffect

    Public Sub New()
        contract = New NonExpiringContract
        effect = New NoEffectGeneralEffect
    End Sub

End Class


<Serializable()> Public Enum ExpirationContractType
    never_expires = 0
    number_of_turns = 1
    status_expire = 2
    battle_expire = 4
End Enum



Public Interface IExpirationContract

    Sub initialize(ByVal values() As Object)
    Function IsExpired(ByVal args() As Object) As Boolean
    ReadOnly Property ExpirationContract() As ExpirationContractType
    ReadOnly Property ContractName() As String

End Interface



Public Interface IGeneralEffect
    Sub Activate(ByRef args() As Object)
End Interface



<Serializable()> Public Class NonExpiringContract : Implements IExpirationContract

    Public Overrides Function tostring() As String 'Implements IExpirationContract.toString
        Return "Manual"
    End Function

    Public ReadOnly Property ExpirationContract() As ExpirationContractType Implements IExpirationContract.ExpirationContract
        Get
            Return ExpirationContractType.never_expires
        End Get
    End Property

    Public Function IsExpired(ByVal args() As Object) As Boolean Implements IExpirationContract.IsExpired
        Return False
    End Function

    Public Sub initialize(ByVal values() As Object) Implements IExpirationContract.initialize
        '// no initialization required
    End Sub

    Public ReadOnly Property ContractName() As String Implements IExpirationContract.ContractName
        Get
            Return "Does not expire"
        End Get
    End Property

End Class



<Serializable()> Public Class TurnNumberExpiringContract : Implements IExpirationContract

    Private _turnGranted As Long
    Private _numberTurns As Long '// the number of turns until expiration

    Public Overrides Function tostring() As String 'Implements IExpirationContract.toString
        Return "Expires in x turns"
    End Function

    Public Property numberTurns() As Long
        Get
            Return _numberTurns
        End Get
        Set(ByVal value As Long)
            _numberTurns = value
        End Set
    End Property

    Public Property turnGranted() As Long
        Get
            Return _turnGranted
        End Get
        Set(ByVal value As Long)
            _turnGranted = value
        End Set
    End Property

    Public ReadOnly Property ExpirationContract() As ExpirationContractType Implements IExpirationContract.ExpirationContract
        Get
            Return ExpirationContractType.number_of_turns
        End Get
    End Property

    Public Function IsExpired(ByVal args() As Object) As Boolean Implements IExpirationContract.IsExpired
        '// args(0) = current turn
        If CLng(args(0)) > _turnGranted + _numberTurns Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Sub initialize(ByVal values() As Object) Implements IExpirationContract.initialize
        '// value(0) = turngranted
        '// value(1) = number of turns
        Try
            _turnGranted = values(0)
            _numberTurns = values(1)
        Catch ex As Exception
            _turnGranted = 0
            _numberTurns = 1
        End Try
    End Sub

    Public ReadOnly Property ContractName() As String Implements IExpirationContract.ContractName
        Get
            Return "Expires in x turns"
        End Get
    End Property
End Class



<Serializable()> Public Class StatusExpiringContract : Implements IExpirationContract

    Private _requiredStatus As GroundUnitStatus_cgd

    Public Overrides Function ToString() As String
        Return "Status"
    End Function

    Public Property requiredStatus() As GroundUnitStatus_cgd
        Get
            Return _requiredStatus
        End Get
        Set(ByVal value As GroundUnitStatus_cgd)
            _requiredStatus = value
        End Set
    End Property

    Public ReadOnly Property ExpirationContract() As ExpirationContractType Implements IExpirationContract.ExpirationContract
        Get
            Return ExpirationContractType.status_expire
        End Get
    End Property

    Public Sub initialize(ByVal values() As Object) Implements IExpirationContract.initialize
        '// values(0) = status required to keep from expiring
        _requiredStatus = values(0)
    End Sub

    Public Function IsExpired(ByVal args() As Object) As Boolean Implements IExpirationContract.IsExpired
        '// args(0) = current status of the owning unit
        Try
            If DirectCast(args(0), GroundUnitStatus_cgd) = _requiredStatus Then
                Return False
            Else
                Return True
            End If
        Catch ex As Exception

        End Try
    End Function

    Public ReadOnly Property ContractName() As String Implements IExpirationContract.ContractName
        Get
            Return "Status"
        End Get
    End Property
End Class



<Serializable()> Public Class BattleExpiringContract : Implements IExpirationContract
    Private _expiresafterLoss As Boolean

    Public Overrides Function ToString() As String
        Return "Battle expiration"
    End Function

    Public Property expiresAfterLoss() As Boolean
        Get
            Return _expiresafterLoss
        End Get
        Set(ByVal value As Boolean)
            _expiresafterLoss = value
        End Set
    End Property

    Public ReadOnly Property ContractName() As String Implements IExpirationContract.ContractName
        Get
            Return "Battle win/loss"
        End Get
    End Property

    Public ReadOnly Property ExpirationContract() As ExpirationContractType Implements IExpirationContract.ExpirationContract
        Get
            Return ExpirationContractType.battle_expire
        End Get
    End Property

    Public Sub initialize(ByVal values() As Object) Implements IExpirationContract.initialize
        '// value(0) is true or false for if it expires after loss (if false, then it expires after a battle win, such as morale boost)
        _expiresafterLoss = values(0)
    End Sub

    Public Function IsExpired(ByVal args() As Object) As Boolean Implements IExpirationContract.IsExpired
        '// args(0) = owning chitmember
        Try
            Dim mem As ChitMember = args(0)

            If mem.battleInvolvedIn Is Nothing Then
                Return False
            End If

            Dim batt As Battle = mem.battleInvolvedIn

            '// if it isn't resolved, don't check
            If batt.BattleResult = BattleResult_cgd.NotFinished Then Return False
            If batt.BattleResult = BattleResult_cgd.Draw Then Return False '// a draw doesn't trip it

            '// so, now the battle is resolved and we need to know if this chit is the winner or not so much.
            If mem.OwningFaction.FactionID = batt.AttackingFactionID Then
                '// it belongs to the "attacking" side
                If batt.BattleResult = BattleResult_cgd.AttackerMarginalVictory OrElse batt.BattleResult = BattleResult_cgd.AttackerVictory Then
                    If _expiresafterLoss = True Then
                        Return False
                    Else
                        Return True
                    End If
                Else
                    If _expiresafterLoss = True Then
                        Return True
                    Else
                        Return False
                    End If
                End If
            Else
                '// it belongs to the "defending" side
                If batt.BattleResult = BattleResult_cgd.DefenderMarginalVictory OrElse batt.BattleResult = BattleResult_cgd.DefenderVictory Then
                    If _expiresafterLoss = True Then
                        Return False
                    Else
                        Return True
                    End If
                Else
                    If _expiresafterLoss = True Then
                        Return True
                    Else
                        Return False
                    End If
                End If

            End If

        Catch ex As Exception
            HandleException("BattleExpiringContract.IsExpired", ex)
            Return False
        End Try
    End Function
End Class


<Serializable()> Public Class NoEffectGeneralEffect : Implements IGeneralEffect

    Public Sub Activate(ByRef args() As Object) Implements IGeneralEffect.Activate
        '// do nothing
    End Sub
End Class